六、API 参考
6.1 tasys 接口详解
6.1.1 taco_sys_set_config
描述
设置公共缓存池方案。
语法
taco_s32 taco_sys_set_config(const taco_config_t *taco_config);
参数说明
| 参数名称 | 描述 | 输入/输出 |
|---|---|---|
taco_config | 指向公共缓存池方案结构体的指针 | 输入 |
返回值
| 返回值 | 描述 |
|---|---|
| 0 | 成功设置公共缓存池方案 |
| 非 0 | 设置失败 |
注意事项
- 支持在多个进程中调用,仅限于首次调用时执行功能,后续调用直接返回失败
- 执行模块反初始化后,已设置的公共缓存池方案同时销毁,下次初始化前需要重新设置
6.1.2 taco_sys_get_config
描述
获取已设置的公共缓存池方案。
语法
taco_s32 taco_sys_get_config(taco_config_t *taco_config);
参数说明
| 参数名称 | 描述 | 输入/输出 |
|---|---|---|
taco_config | 指向存储公共缓存池配置的结构体指针 | 输出 |
返回值
| 返回值 | 描述 |
|---|---|
| 0 | 成功获取公共缓存池方案 |
| 非 0 | 获取失败 |
注意事项
- 该函数用于获取之前通过
taco_sys_set_config设置的公共缓存池配置信息 - 需要确保传入的
taco_config指针指向有效的内存区域,函数会将获取到的配置信息填充到该结构体中 - 只有在成功调用
taco_sys_set_config后,才能通过此函数获取到有效的配置信息
6.1.3 taco_sys_create_pool
描述
创建一个缓存池。
详情 创建一个缓存池,常用于为特定的业务提供专用缓存,以保证服务质量(QoS)。
语法
taco_pool_t taco_sys_create_pool(const taco_pool_config_t *pool_cfg);
参数说明
| 参数名称 | 描述 | 输入/输出 |
|---|---|---|
pool_cfg | 缓存池配置 | 输入 |
返回值
| 返回值 | 描述 |
|---|---|
| 大于等于 0 的整数 | 成功,返回值即为 pool_id |
TACO_INVALID_POOLID | 失败 |
注意事项
- 本接口创建的缓存池与公共缓存池的区别在于:
- 公共缓存池方案可一次创建多个缓存池,而此接口每次调用只创建一个缓存池
- 公共缓存池是必须创建的,而此接口是可选的,按需创建
6.1.4 taco_sys_destroy_pool
描述
销毁指定的缓存池。
语法
taco_s32 taco_sys_destroy_pool(taco_pool_t pool);
参数说明
| 参数名称 | 描述 | 输入/输出 |
|---|---|---|
pool | 创建的缓存池 ID | 输入 |
返回值
| 返回值 | 描述 |
|---|---|
| 0 | 成功 |
| 非 0 | 失败 |
注意事项
- 本接口只用于销毁使用
taco_sys_create_pool接口创建的缓存池
6.1.5 taco_sys_get_block
描述
从公共缓存池或指定缓存池中申请一个缓存块,并获得该缓存块的 VBID(Virtual Block ID)。
语法
taco_blk_t taco_sys_get_block(
taco_pool_t pool,
taco_u64 blk_size,
const taco_char *zone_name
);
参数说明
| 参数名称 | 描述 | 输入/输出 |
|---|---|---|
pool | 缓存池 ID。 - 若想从公共缓存池中获取 VB,则传入特殊值 TACO_INVALID_POOLID - 若想从特定的 pool 中获取 VB,则传入一个有效的 pool_id | 输入 |
blk_size | 需要从缓存池中获取的 VB 的大小(以字节为单位) | 输入 |
zone_name | Zone 名称。 - 若为 NULL,则在默认的 zone 上按规则获取 VB - 若非 NULL,则在指定的 zone 上按规则获取 VB | 输入 |
返回值
| 返回值 | 描述 |
|---|---|
| 0 | 失败 |
| 非 0 | 所分配缓存块的 block ID |
6.1.6 taco_sys_get_block_size
描述
获取一个缓存块的容量。
语法
taco_s32 taco_sys_get_block_size(
taco_pool_t pool,
taco_blk_t block,
taco_u64 *get_size
);
参数说明
| 参数名称 | 描述 | 输入/输出 |
|---|---|---|
pool | 缓存池 ID | 输入 |
block | VB 块的 ID | 输入 |
get_size | 指向存储块大小的指针变量,用于输出获取到的块大小 | 输出 |
返回值
| 返回值 | 描述 |
|---|---|
| 0 | 成功获取缓存块大小 |
| 非 0 | 获取失败 |
注意事项
- 此函数用于查询已分配缓存块的实际大小,可用于验证分配的内存块是否符合预期
- 需要传入有效的
pool和block参数才能正确获取块大小 get_size参数必须指向一个有效的内存地址,函数会将获取到的块大小写入该地址指向的变量中- 在调用此函数前,确保对应的缓存块仍然有效且未被释放
6.1.7 taco_sys_release_block
描述
释放一个缓存块。
详情
将缓存块归还给所属的 pool,以便循环使用。
语法
taco_s32 taco_sys_release_block(taco_blk_t block);
参数说明
| 参数名称 | 描述 | 输入/输出 |
|---|---|---|
block | 要释放的 VB 的 ID | 输入 |
返回值
| 返回值 | 描述 |
|---|---|
| 0 | 成功 |
| 非 0 | 失败 |
注意事项
- 在释放缓存块之前,必须确保已经解除所有虚拟地址映射关系
- 释放后的缓存块可以被其他请求重新分配使用
6.1.8 taco_sys_handle2_phys_addr
描述
获取一个缓存块的物理地址。
语法
taco_u64 taco_sys_handle2_phys_addr(taco_blk_t block);
参数说明
| 参数名称 | 描述 | 输入/输出 |
|---|---|---|
block | 需要获取的 VB 的 ID | 输入 |
返回值
| 返回值 | 描述 |
|---|---|
| 非 0 | 成功 |
| 0 | 失败 |
注意事项
- 该函数返回的是缓存块在物理内存中的起始地址
- 物理地址可以直接用于硬件访问
6.1.9 taco_sys_handle2_meta_addr
描述
获取一个缓存块的元数据的物理地址。
详情
每个 VB 缓存块都自动关联一个元数据(metadata),其大小在创建 pool 时指定(大小可以为 0)。本接口用于获取元数据的物理地址。
语法
taco_u64 taco_sys_handle2_meta_addr(taco_blk_t block);
参数说明
| 参数名称 | 描述 | 输入/输出 |
|---|---|---|
block | 目标 VB 的 ID | 输入 |
返回值
| 返回值 | 描述 |
|---|---|
| 非 0 | 成功 |
| 0 | 失败 |
注意事项
- VB 元数据的生命周期与 VB 本身相同,所以 SDK 内部处理,不需要显式地创建和销毁
6.1.10 taco_sys_mmz_alloc
描述
从 MMZ 内存区中申请一块内存。
详情
通过本接口申请的内存可以用作承载流式数据的环形缓冲区,以及任何用户认为合适的用途。
语法
taco_s32 taco_sys_mmz_alloc(
taco_u64 *phys_addr,
const taco_char *mmb,
const taco_char *zone_name,
taco_u32 len
);
参数说明
| 参数名称 | 描述 | 输入/输出 |
|---|---|---|
phys_addr | 申请的内存区域的物理地址 | 输出 |
mmb | 给申请的内存区域取的名字,若为 NULL,则名字为 null,最大长度 32 bytes | 输入 |
zone_name | 申请的内存区域的 zone 的名字 | 输入 |
len | 申请的内存区域的长度 | 输入 |
返回值
| 返回值 | 描述 |
|---|---|
| 0 | 成功 |
| 非 0 | 失败 |
注意事项
- 为了控制内存碎片化风险,不宜频繁申请释放 MMB
6.1.11 taco_sys_mmz_free
描述
释放一个 MMB 内存块。
语法
taco_s32 taco_sys_mmz_free(taco_u64 phys_addr);
参数说明
| 参数名称 | 描述 | 输入/输出 |
|---|---|---|
phys_addr | 要释放的 MMB 内存块的物理地址 | 输入 |
返回值
| 返回值 | 描述 |
|---|---|
| 0 | 成功 |
| 非 0 | 失败,返回错误码 |
注意事项
- 为了控制内存碎片化风险,不宜频繁申请释放 MMB
6.1.12 taco_sys_mmap_noncache
描述
映射一个物理地址,获得虚拟地址,类型为不可缓存。
语法
taco_void * taco_sys_mmap_noncache(taco_u64 phys_addr, taco_u32 size);
参数说明
| 参数名称 | 描述 | 输入/输出 |
|---|---|---|
phys_addr | 需要映射的物理地址 | 输入 |
size | 需要映射的物理地址区域大小 | 输入 |
返回值
| 返回值 | 描述 |
|---|---|
非 NULL | 成功 |
NULL | mmap 失败,提示错误信息 |
6.1.13 taco_sys_mmap_cache
描述
映射一个物理地址,获得虚拟地址,类型为可缓存。
语法
taco_void * taco_sys_mmap_cache(taco_u64 phys_addr, taco_u32 size);
参数说明
| 参数名称 | 描述 | 输入/输出 |
|---|---|---|
phys_addr | 需要映射的物理地址 | 输入 |
size | 需要映射的物理地址区域大小 | 输入 |
返回值
| 返回值 | 描述 |
|---|---|
非 NULL | 成功 |
NULL | mmap 失败,提示错误信息 |
6.1.14 taco_sys_munmap
描述
解除给定虚拟地址的映射关系。
语法
taco_s32 taco_sys_munmap(taco_void *virt_addr, taco_u32 size);
参数说明
| 参数名称 | 描述 | 输入/输出 |
|---|---|---|
virt_addr | 需要解除映射的虚拟地址 | 输入 |
size | 需要解除映射的虚拟地址区域的大小 | 输入 |
返回值
| 返回值 | 描述 |
|---|---|
| 0 | 成功 |
TACO_ERR_ILLEGAL_PARAM | 失败,虚拟地址 virt_addr 无效,提示错误信息 |
TACO_ERR_UNEXIST | 失败,munmap 失败,提示错误信息 |
6.1.15 taco_sys_cache_invalidate
描述
将 cache 内容标记为无效。
语法
taco_s32 taco_sys_cache_invalidate(taco_void *virt_addr, taco_u32 size);
参数说明
| 参数名称 | 描述 | 输入/输出 |
|---|---|---|
virt_addr | 虚拟地址 | 输入 |
size | 虚拟地址指向空间的内存大小 | 输入 |
返回值
| 返回值 | 描述 |
|---|---|
| 0 | 成功 |
| 非 0 | 失败 |
6.1.16 taco_sys_cache_flush
描述
将 cache 中缓存的数据写入主内存。
语法
taco_s32 taco_sys_cache_flush(taco_void *virt_addr, taco_u32 size);
参数说明
| 参数名称 | 描述 | 输入/输出 |
|---|---|---|
virt_addr | 虚拟地址 | 输入 |
size | 虚拟地址指向空间的内存大小 | 输入 |
返回值
| 返回值 | 描述 |
|---|---|
| 0 | 成功 |
| 非 0 | 失败 |
6.1.17 使用示例
对于开发者而言,常用的接口主要是申请 block 内存,获取物理地址,获取虚拟地址。接口文件包含在 taco_sys_api.h 中,链接库名为 libtacosys.so。
#include <stdio.h>
#include <stdlib.h>
#include "taco_sys_api.h"
int main()
{
// tasys 初始化
taco_sys_init();
int total_size_in = 640 * 640 * 1.5;
// 申请 block 内存,从公共缓存池或指定缓存池中申请一个缓存块
// TACO_INVALID_POOLID 为特殊值,表示从公共缓存池中申请
// "anonymous" 为申请的内存区域的 zone 的名字
unsigned int blk_id_in = taco_sys_get_block(TACO_INVALID_POOLID, total_size_in, "anonymous");
// 通过 block ID 获取物理地址
unsigned long long physAddr_in = taco_sys_handle2_phys_addr(blk_id_in);
// 通过物理地址获取虚拟地址,为 uncache 的内存
unsigned char* data_in = (unsigned char*)taco_sys_mmap_noncache(physAddr_in, total_size_in);
// 释放虚拟地址,解除映射关系
taco_sys_munmap(data_in, total_size_in);
// 归还 block 至缓存池,注意:释放 blk 之前请解除映射关系
taco_sys_release_block(blk_id_in);
// 如果不想从缓存池申请内存,也可以通过 mmz_alloc 申请物理内存
// "mmb" 是给申请的内存区域取的名字
taco_sys_mmz_alloc(&physAddr_in, "mmb", "anonymous", total_size_in);
return 0;
}
6.2 taCV 接口详解
模块提供的所有接口都是同步接口,用户在调用接口时需要同时提供输入输出 buffer,如果接口返回成功,则输出 buffer 中已含有输出图像。接口依赖 tasys 模块提供帧缓存,用户在创建公共缓存池时,应为本模块预留合适大小和数量的帧缓存。taCV 提供图像处理 SPP 硬件加速接口,可以对图像做 crop、resize 和格式转换的操作。
6.2.1 ta_cv_image_resize
描述
实现对图像的 resize 等操作,只支持 down scale。
语法
tacv_status_t ta_cv_image_resize(
ta_cv_resize_image_t resize_attr,
ta_image_t input,
ta_image_t output);
参数说明
| 参数名称 | 描述 | 输入/输出 |
|---|---|---|
resize_attr | resize 图像信息 | 输入 |
input | 输入图像信息 | 输入 |
output | 输出图像信息 | 输出 |
返回值
| 返回值 | 描述 |
|---|---|
| 0 | 成功 |
| 非 0 | 失败 |
格式支持
| Num | Input_Image_Format | Output_Image_Format |
|---|---|---|
| 1 | FORMAT_NV12 | FORMAT_NV12 |
注意事项
- 最大缩放比为 128,最大输入输出分辨率为 4096×2160
- 缩放(resize)操作只支持缩小
crop_width >= resize_width- 宽/高需为 16 的倍数
6.2.2 ta_cv_image_crop
描述
实现对图像的 crop 操作。
语法
tacv_status_t ta_cv_image_crop(
int crop_num,
ta_cv_rect_t* rects,
ta_image_t input,
ta_image_t* output);
参数说明
| 参数名称 | 描述 | 输入/输出 |
|---|---|---|
crop_num | 需要 crop 的数量 | 输入 |
rects | crop 信息指针 | 输入 |
input | 输入图像信息 | 输入 |
output | 输出图像信息指针 | 输出 |
返回值
| 返回值 | 描述 |
|---|---|
| 0 | 成功 |
| 非 0 | 失败 |
格式支持
| Num | Input_Image_Format | Output_Image_Format |
|---|---|---|
| 1 | FORMAT_NV12 | FORMAT_NV12 |
注意事项
- 最大输入输出分辨率为 4096×2160
crop_width和crop_height必须为偶数- 要确保裁剪区域不会超出原始图像的右边界(水平方向)和下边界(垂直方向)
- 宽/高需为 16 的倍数
6.2.3 ta_cv_yuv2bgr_ext
描述
实现 YUV 格式到 RGB 格式的转换。
语法
ta_status_t ta_cv_yuv2bgr_ext(
int image_num,
ta_image_t* input,
ta_image_t* output,
ta_hw_select_t hw_select);
参数说明
| 参数名称 | 描述 | 输入/输出 |
|---|---|---|
image_num | 输入图片数量 | 输入 |
input | 输入图片结构体指针 | 输入 |
output | 输出图片结构体指针 | 输出 |
hw_select | 选择执行的硬件 | 输入 |
返回值
| 返回值 | 描述 |
|---|---|
| 0 | 成功 |
| 非 0 | 失败 |
格式支持
| Num | Input_Image_Format | Output_Image_Format |
|---|---|---|
| 1 | FORMAT_NV12 | FORMAT_BGR_PLANAR |
| 2 | FORMAT_NV12 | FORMAT_RGB_PLANAR |
| 3 | FORMAT_NV12 | FORMAT_RGB_PACKED |
| 4 | FORMAT_NV12 | FORMAT_BGR_PACKED |
注意事项
- 所有输入图像的
image_format、data_type、width、height必须一致 - 所有输出图像的
image_format、data_type、width、height必须一致 - 输出图像的
width、height必须与输入图像一致
6.2.4 ta_cv_image_csc_convert_to
描述
实现对图像的 crop + resize + csc 等操作。
语法
tacv_status_t ta_cv_image_csc_convert_to(
ta_image_t input,
ta_image_t output,
ta_cv_rect_t crop_rect,
ta_cv_resize_image_t* resize,
csc_type_t csc_typ);
参数说明
| 参数名称 | 描述 | 输入/输出 |
|---|---|---|
input | 输入图像信息 | 输入 |
output | 输出图像信息 | 输出 |
crop_rect | crop 参数 | 输入 |
resize | resize 图像的参数指针 | 输入 |
csc_typ | 颜色空间转换类型 | 输入 |
返回值
| 返回值 | 描述 |
|---|---|
| 0 | 成功 |
| 非 0 | 失败 |
格式支持
| Num | Input_Image_Format | Output_Image_Format |
|---|---|---|
| 1 | FORMAT_NV12 | FORMAT_NV12 |
| 2 | FORMAT_NV12 | FORMAT_NV21 |
| 3 | FORMAT_NV12 | FORMAT_RGB_PACKED |
| 4 | FORMAT_NV12 | FORMAT_BGR_PACKED |
| 5 | FORMAT_NV12 | FORMAT_RGB_PLANAR |
| 6 | FORMAT_NV12 | FORMAT_BGR_PLANAR |
| 7 | FORMAT_NV12 | FORMAT_ABGR_PACKED |
| 8 | FORMAT_NV12 | FORMAT_ARGB_PACKED |
注意事项
- 最大缩放比为 128,最大输入输出分辨率为 4096×2160
- 缩放(resize)操作只支持缩小
crop_width >= resize_width- 宽/高需为 16 的倍数
6.2.5 ta_cv_image_jpeg_enc
描述
实现对图像进行 JPEG 编码操作。
语法
tacv_status_t ta_cv_image_jpeg_enc(
ta_image_t* src,
unsigned int jpeg_data_blk,
size_t* out_size,
int quality_factor);
参数说明
| 参数名称 | 描述 | 输入/输出 |
|---|---|---|
src | 输入图像指针 | 输入 |
jpeg_data_blk | 输出 buffer 的 blk_id | 输入 |
out_size | 输出 buffer 的 size 指针 | 输入/输出 |
quality_factor | 图像质量因子 | 输入 |
返回值
| 返回值 | 描述 |
|---|---|
| 0 | 成功 |
| 非 0 | 失败 |
格式支持
| Num | Input_Image_Format | Output_Image_Format |
|---|---|---|
| 1 | FORMAT_NV12 | |
| 2 | FORMAT_YUV420P |
注意事项
- 申请输出 buffer 的大小要大于等于输入 buffer 的大小
- 支持大小 96×32 到 8192×8192(宽×高)
width和height必须为偶数- 图像质量因子
quality_factor的取值范围为(0, 100]
6.2.6 ta_cv_image_jpeg_dec
描述
实现对 JPEG 图像进行解码操作。
语法
tacv_status_t ta_cv_image_jpeg_dec(
size_t in_size,
unsigned int jpeg_in_blk_id,
ta_image_t *dst);
参数说明
| 参数名称 | 描述 | 输入/输出 |
|---|---|---|
in_size | 输入图像 buffer 大小 | 输入 |
jpeg_in_blk_id | 输入图像 block_id | 输入 |
dst | 输出图像信息指针 | 输入/输出 |
返回值
| 返回值 | 描述 |
|---|---|
| 0 | 成功 |
| 非 0 | 失败 |
格式支持
| Num | Input_Image_Format | Output_Image_Format |
|---|---|---|
| 1 | FORMAT_NV12 | |
| 2 | FORMAT_NV21 | |
| 3 | FORMAT_RGB_PACKED | |
| 4 | FORMAT_BGR_PACKED | |
| 5 | FORMAT_BGR_PLANAR | |
| 6 | FORMAT_RGB_PLANAR |
注意事项
- 最大输入输出分辨率 32768×32768
- 宽/高需为 16 的倍数
- 调用接口前需要创建输出图像
- 调用接口前需要准备好输入输出 buffer
6.2.7 taCV 示例程序
#include "ta_cv_api_ext_c.h"
#include "taco_sys_api.h"
#include <stdio.h>
#include <string.h>
int main(int argc, const char** argv)
{
int ret = 0;
int width = atoi(argv[2]);
int height = atoi(argv[3]);
int out_width = atoi(argv[4]);
int out_height = atoi(argv[5]);
int format = FORMAT_NV12;
int total_size_in = width * height * 1.5;
int total_size_out = out_width * out_height * 1.5;
total_size_in = SAMPLE_ALIGN(4096, total_size_in);
total_size_out = SAMPLE_ALIGN(4096, total_size_out);
unsigned long long physAddr_in = 0;
unsigned long long physAddr_out = 0;
// 初始化 tasys,获取 block
taco_sys_init();
ta_avframe_t frame_in[1], frame_out[1];
unsigned int blk_id_in = taco_sys_get_block(0xffffffff, total_size_in, "anonymous");
char str_blk_id_in[16];
physAddr_in = taco_sys_handle2_phys_addr(blk_id_in);
unsigned char* data_in = (unsigned char*)taco_sys_mmap_noncache(physAddr_in, total_size_in);
sprintf(str_blk_id_in, "%u", blk_id_in);
/* 填充输入 av_frame */
TA_AVDictionaryEntry elems;
elems.value = str_blk_id_in;
TA_AVDictionary metadata_in;
metadata_in.elems = &elems;
frame_in[0].data[0] = data_in;
frame_in[0].metadata = &metadata_in;
frame_in[0].width = width;
frame_in[0].height = height;
frame_in[0].format = TA_AV_PIX_FMT_NV12;
/* 填充输出 av_frame */
char str_blk_id_out[16];
unsigned int blk_id_out = taco_sys_get_block(0xffffffff, total_size_out, "anonymous");
physAddr_out = taco_sys_handle2_phys_addr(blk_id_out);
unsigned char* data_out = (unsigned char*)taco_sys_mmap_noncache(physAddr_out, total_size_out);
sprintf(str_blk_id_out, "%u", blk_id_out);
TA_AVDictionaryEntry elems_out;
elems_out.value = str_blk_id_out;
TA_AVDictionary metadata_out;
metadata_out.elems = &elems_out;
frame_out[0].data[0] = data_out;
frame_out[0].metadata = &metadata_out;
frame_out[0].width = out_width;
frame_out[0].height = out_height;
frame_out[0].format = TA_AV_PIX_FMT_NV12;
FILE *fd = fopen(argv[1], "rb");
fread(data_in, total_size_in, 1, fd);
fclose(fd);
// 创建图像结构体
ta_image_t image_in, image_out;
ta_cv_image_create(height, width, (ta_image_format_ext_t)format, DATA_TYPE_EXT_1N_BYTE, &image_in, (ta_avframe_t*)&frame_in[0]);
ta_cv_image_create(out_height, out_width, (ta_image_format_ext_t)format, DATA_TYPE_EXT_1N_BYTE, &image_out, (ta_avframe_t*)&frame_out[0]);
ta_cv_resize_image_t resize_attr = {0};
memset(&resize_attr, 0, sizeof(ta_cv_resize_image_t));
ta_cv_resize_t resize = {0};
resize.in_height = height;
resize.in_width = width;
resize.out_height = out_height;
resize.out_width = out_width;
resize.start_x = 0;
resize.start_y = 0;
resize_attr.resize_img_attr = &resize;
resize_attr.interpolation = 3;
// 调用函数
ret = ta_cv_image_resize(&resize_attr, image_in, image_out);
fd = fopen("resize_output.bin", "wb");
fwrite(data_out, total_size_out, 1, fd);
fclose(fd);
// 释放 block
taco_sys_munmap(data_in, total_size_in);
taco_sys_release_block(blk_id_in);
taco_sys_munmap(data_out, total_size_out);
taco_sys_release_block(blk_id_out);
ta_cv_image_destroy(&image_in);
ta_cv_image_destroy(&image_out);
return ret;
}
6.3 taRuntime 接口详解
6.3.1 ta_runtime_init
描述
实现模块初始化流程,为后续模型加载与推理运行做好软硬件准备。
详情
该接口完成硬件和软件相关资源的初始化操作。主要包括初始化 NPU 硬件资源和驱动程序。
本函数应在其他接口调用前执行,每个进程仅需调用一次,且需要与 ta_runtime_deinit 接口配对使用。若未调用该接口即尝试加载模型或进行推理,相关接口会返回失败。
语法
taco_status_t ta_runtime_init();
返回值
| 错误码 | 描述 |
|---|---|
| 0 | 成功 |
| 非 0 | 失败 |
注意事项
- 支持多进程、多线程,每个进程都应调用一次,最先调用的生效
- 每个进程仅调用一次即可,不应每个线程都调用
6.3.2 ta_runtime_deinit
描述
实现模块反初始化流程,包括释放已分配的各种资源,关闭 NPU 服务。
详情
本接口用于在应用程序退出前对各种资源进行清理,释放初始化和运行阶段所申请的资源。
语法
taco_status_t ta_runtime_deinit();
返回值
| 错误码 | 描述 |
|---|---|
| 0 | 成功 |
| 非 0 | 失败 |
注意事项
- 支持多进程、多线程,每个进程都应调用一次,最后调用的生效
- 每个进程仅调用一次即可,不应每个线程都调用
6.3.3 ta_runtime_load_model_from_file
描述
从文件系统中读取模型文件,解析文件信息并创建可在板端运行的网络模型。
详情
接口从文件系统中读取的是 NB 格式的模型文件,加载到系统域内存区。接口内部对 NB 文件进行解析,提取出 NPU 推理所需的指令流和权重数据,保存在 NN 域内存区。文件解析完毕后,系统域的输入数据就不再需要了,用户可以释放该 buffer。
语法
taco_status_t ta_runtime_load_model_from_file(
ta_runtime_context *context,
const char *model_path,
uint32_t core_index);
参数说明
| 参数 | 描述 | 输入/输出 |
|---|---|---|
context | ta_runtime_context 类型的结构体指针。该结构体由 SDK 内部逻辑维护,用户需要在相关接口中传递该指针,除此之外无需使用该结构体 | 输入/输出 |
model_path | 模型路径 | 输入 |
core_index | NPU 设备支持两个 cluster,编号为 0 和 1。此参数用于指定模型部署至哪个 cluster 上运行。若模型类型为 dual-core,则该参数必须设置为 0 | 输入 |
返回值
| 错误码 | 描述 |
|---|---|
| 0 | 成功 |
| 非 0 | 失败 |
注意事项
- 确保在调用该接口前某个进程执行了模块初始化操作
6.3.4 ta_runtime_load_model_at_ddr
描述
从 DDR 内存中读取模型信息,解析并创建可在板端运行的网络。
详情
接口从系统域输入 buffer 读取的是 NB 格式的模型信息,接口内部对 NB 信息进行解析,提取出 NPU 推理所需的指令流和权重数据,保存在 NN 域内存区。解析完成后,系统域输入 buffer 就不再需要了,用户可以释放该 buffer。
语法
taco_status_t ta_runtime_load_model_at_ddr(
ta_runtime_context *context,
void* model,
const uint64_t model_size,
uint32_t core_index);
参数说明
| 参数 | 描述 | 输入/输出 |
|---|---|---|
context | 同 ta_runtime_load_model_from_file | 输入 |
model | 模型数据指针 | 输入 |
model_size | 模型尺寸 | 输入 |
core_index | 同 ta_runtime_load_model_from_file | 输入 |
返回值
| 错误码 | 描述 |
|---|---|
| 0 | 成功 |
| 非 0 | 失败 |
注意事项
- 确保在调用该接口前某个进程执行了模块初始化操作
6.3.5 ta_runtime_query
描述
查询模型输入输出信息、模型推理的总时间,以及模型相关信息。
语法
taco_status_t ta_runtime_query(
ta_runtime_context *context,
const uint32_t property,
void *value);
参数说明
| 参数 | 描述 | 输入/输出 |
|---|---|---|
context | 同 ta_runtime_load_model_from_file | 输入 |
property | 查询指令 | 输入 |
value | 存放返回结果的 buffer 地址 | 输入/输出 |
返回值
| 错误码 | 描述 |
|---|---|
| 0 | 成功 |
| 非 0 | 失败 |
查询命令
| 查询命令 | 描述 | 返回值类型 |
|---|---|---|
TACONN_QUERY_DRIVER_VERSION | 查询驱动版本 | uint32_t |
TACONN_QUERY_IN_OUT_NUM | 查询输入输出 tensor 个数 | taconn_input_ouput_num_t |
TACONN_QUERY_INPUT_ATTR | 查询输入 tensor 属性 | taconn_inout_attr_t |
TACONN_QUERY_OUTPUT_ATTR | 查询输出 tensor 属性 | taconn_inout_attr_t |
TACONN_QUERY_LAYER_COUNT | 查询网络模型总层数 | uint32_t |
TACONN_QUERY_NETWORK_NAME | 查询网络名称 | char[] |
TACONN_QUERY_PROFILING | 查询模型推理性能数据 | taconn_profile_t |
TACONN_NETWORK_MEMORY_POOL_SIZE | 查询模型占用的 video_memory 内存大小 | taconn_memory_size_t |
6.3.6 ta_runtime_set_input_cva
描述
用于设置模型的输入数据(图像或张量),输入地址类型为 CPU 虚拟地址,支持拷贝和映射两种访问方式。
详情
所谓输入数据,具体是指模型的第一层算子所需的输入数据,它的具体形式取决于模型的要求。多数模型需要一幅图像作为输入,有些模型可能需要两幅或者更多图像。而图像格式可以有 NV12、RGB、Tensor 等多种选项,图像的数据精度一般是 INT8。
该接口支持一次设置多个输入,因此用户需要提供一个 taconn_input_t 结构体的数组,并且确保结构体的所有参数均已正确赋值,未使用的参数应清零。
如果使用拷贝方式,本接口会在 NN 域申请一个 buffer(涉及存储空间+虚拟地址两种资源),将输入数据拷贝到 NN 域 buffer,所以接口返回后输入 buffer 可以立即释放。NN 域 buffer 会在推理结束后由 SDK 自动释放。
如果使用映射方式,本接口会在 NN 域申请一段虚拟地址,并与输入数据所在的内存页面建立映射关系。接口返回后输入 buffer 不能立即释放,必须等推理结束后才能释放。NN 域虚拟地址会在推理结束后由 SDK 自动释放。
语法
taco_status_t ta_runtime_set_input_cva(
ta_runtime_context *context,
uint32_t input_num,
taconn_input_t *input);
参数说明
| 参数 | 描述 | 输入/输出 |
|---|---|---|
context | 同 ta_runtime_load_model_from_file | 输入 |
input_num | 模型输入的个数 | 输入 |
input | 指针,指向一个 taconn_input_t 类型的数组 | 输入 |
返回值
| 错误码 | 描述 |
|---|---|
| 0 | 成功 |
| 非 0 | 失败 |
注意事项
- 结构体在赋值前应整体清零,在参数有误的情况下,清零有利于故障现象的一致性
- 输入数量不应超过模型所需的输入个数,否则接口会报错
- 输入数据的地址必须是 256 对齐(地址指针的低 8 位全为 0),否则接口会报错
6.3.7 ta_runtime_set_input_pha
描述
用于设置模型的输入数据,输入地址类型为物理地址。
详情
本接口内部将输入的物理地址映射为 NPU 虚拟地址,一次推理结束后,接口内部会尝试把虚拟地址缓存到内部查找表中,待模块卸载时统一释放。
该接口支持多个输入,因此用户需要提供一个 taconn_input_phy_t 结构体的数组,并且确保结构体的所有参数均已正确赋值,未使用的参数应清零。
本接口内部在 NN 域申请一段虚拟地址,并与输入数据所在的内存页面建立映射关系。接口返回后输入 buffer 不能立即释放,必须等推理结束后才能释放。NN 域虚拟地址会优先缓存在接口内部的查找表中,待模块销毁时由 SDK 自动释放;如果未能缓存到查找表则会立即释放。
语法
taco_status_t ta_runtime_set_input_pha(
ta_runtime_context *context,
uint32_t input_num,
taconn_input_phy_t *input);
参数说明
| 参数 | 描述 | 输入/输出 |
|---|---|---|
context | 同 ta_runtime_load_model_from_file | 输入 |
input_num | 模型输入的个数 | 输入 |
input | 指向 taconn_input_phy_t 类型结构体数组。每个元素代表一个输入的物理地址段信息,包括物理地址表和对应大小表 | 输入 |
返回值
| 错误码 | 描述 |
|---|---|
| 0 | 成功 |
| 非 0 | 失败 |
注意事项
- 用户应在开始推理前完成输入 buffer 的设置,如果设置不全,推理接口会报错
- 本接口允许用户针对同一目标通道多次设置输入 buffer,旧的设置自动失效
- 结构体在赋值前应整体清零,在参数有误的情况下,清零有利于故障现象的一致性
- 输入数量不应超过模型所需的输入个数,否则接口会报错
- 输入数据的地址必须是 256 对齐(地址指针的低 8 位全为 0),否则接口会报错
6.3.8 ta_runtime_create_buffer
描述
用于在 NN 域创建一个保存推理输出结果的缓冲区。
详情
本接口与 ta_runtime_set_output() 接口配合使用,作为该接口的前序接口,用于准备模型输出 buffer。
用户在调用本接口时,仅需传入所需 buffer 的大小,接口内部会自动分配内存并填充 taconn_buffer_t 结构体内容,包括数据指针、buffer size 等信息。结构体 data 字段指向的地址是一个可供 CPU 访问的虚拟地址指针,用户可通过该指针读取推理输出结果。
语法
taco_status_t ta_runtime_create_buffer(
ta_runtime_context *context,
uint32_t size,
taconn_buffer_t *buffer);
参数说明
| 参数 | 描述 | 输入/输出 |
|---|---|---|
context | 同 ta_runtime_load_model_from_file | 输入 |
size | 需要创建的 buffer 大小 | 输入 |
buffer | 指针,指向一个 taconn_buffer_t 结构体 | 输出 |
返回值
| 错误码 | 描述 |
|---|---|
| 0 | 成功 |
| 非 0 | 失败 |
注意事项
- 用户需要根据模型情况计算 buffer 大小,如果 buffer 不够大,后序接口会失败
- 本接口应与
ta_runtime_destroy_buffer()接口成对使用
6.3.9 ta_runtime_destroy_buffer
描述
销毁由 ta_runtime_create_buffer() 创建的 NN 域 buffer,并释放对应的 CPU 虚拟地址资源。
语法
taco_status_t ta_runtime_destroy_buffer(
ta_runtime_context *context,
taconn_buffer_t *buffer);
参数说明
| 参数 | 描述 | 输入/输出 |
|---|---|---|
context | 同 ta_runtime_load_model_from_file | 输入 |
buffer | 指向待销毁的 taconn_buffer_t 类型结构体。该结构体需由 ta_runtime_create_buffer() 创建,函数调用后其内部数据指针即失效 | 输入&输出 |
返回值
| 错误码 | 描述 |
|---|---|
| 0 | 成功 |
| 非 0 | 失败 |
注意事项
- 本接口应与
ta_runtime_create_buffer()接口成对使用 - 用户程序应在销毁前停止访问
taconn_buffer_t的成员变量 - 应避免多次调用销毁同一 buffer 结构体,或销毁未初始化的 buffer,否则产生 UB 行为
6.3.10 ta_runtime_set_output
描述
设置模型推理的输出 buffer。
详情
本接口为模型的指定输出通道设置一个 NN 域输出 buffer,模型推理结束后,用户通过 NN 域 buffer 对应的 CPU 虚拟地址读取推理结果。
本接口与 ta_runtime_create_buffer() 接口配合使用,作为该接口的后序接口。
语法
taco_status_t ta_runtime_set_output(
ta_runtime_context *context,
uint32_t output_num,
taconn_buffer_t *buffer);
参数说明
| 参数 | 描述 | 输入/输出 |
|---|---|---|
context | 同 ta_runtime_load_model_from_file | 输入 |
output_num | 模型的输出个数 | 输入 |
buffer | taconn_buffer_t 结构体指针 | 输入 |
返回值
| 错误码 | 描述 |
|---|---|
| 0 | 成功 |
| 非 0 | 失败 |
注意事项
- 用户应在开始推理前设置输出 buffer,否则推理接口会报错
6.3.11 ta_runtime_invalidate_buffer
描述
将 CPU cache 中与 NN 域 buffer 对应的虚拟地址标记为 invalid,确保下次会从 DDR 中读取数据。
详情
NPU 完成推理后,用户程序读取推理结果前需调用本接口,确保 CPU 能够读取到 DDR 中的最新数据,而不是从缓存中读取旧数据。
语法
taco_status_t ta_runtime_invalidate_buffer(
ta_runtime_context *context,
taconn_buffer_t *buffer);
参数说明
| 参数 | 描述 | 输入/输出 |
|---|---|---|
context | 同 ta_runtime_load_model_from_file | 输入 |
buffer | 指向 taconn_buffer_t 类型结构体的指针,表示待刷新缓存的一块 NN 域缓冲区。该结构体应由 ta_runtime_create_buffer() 创建并合法初始化 | 输入 |
返回值
| 错误码 | 描述 |
|---|---|
| 0 | 成功 |
| 非 0 | 失败 |
6.3.12 ta_runtime_run_network
描述
执行一次模型推理。
详情
在调用本接口进行推理前,需要先设置好模型的输入输出 buffer。
语法
taco_status_t ta_runtime_run_network(ta_runtime_context *context);
参数说明
| 参数 | 描述 | 输入/输出 |
|---|---|---|
context | 同 ta_runtime_load_model_from_file | 输入 |
返回值
| 错误码 | 描述 |
|---|---|
| 0 | 成功 |
| 非 0 | 失败 |
6.3.13 ta_runtime_destroy_context
描述
销毁 NNRT 上下文对象,并释放其关联的所有资源。
详情
该接口用于释放上下文对象 ta_runtime_context 及其内部管理的所有资源。
调用后,传入的 context 指针将被置为 0,表示已无效,不可再被用于任何 NNRT 操作。
语法
taco_status_t ta_runtime_destroy_context(ta_runtime_context *context);
参数说明
| 参数 | 描述 | 输入/输出 |
|---|---|---|
context | 指向要销毁的 ta_runtime_context 结构体指针 | 输入/输出 |
返回值
| 错误码 | 描述 |
|---|---|
| 0 | 成功 |
| 非 0 | 失败 |
6.4 taOpenCV 接口说明
TACO SDK 提供的 taOpenCV 库是在开源社区版本的基础上对部分常用算法实现了硬件加速,具体来说就是基于玄铁 C920 CPU 的 RVV 扩展指令集对图像缩放、插值滤波、颜色空间变换、通道分离合并、二值化、LK 光流、金字塔等常用算子算法进行了向量加速优化。
TACO SDK 中提供的 taOpenCV 相关版本信息如下。
| OpenCV 版本 | OS 版本 | CPU 版本 | RVV 版本 |
|---|---|---|---|
| 4.5.4 | Linux 6.6 | 玄铁 C920V2 | 1.0 |
关于 OpenCV 库的使用说明可参考 「OpenCV 官方网站」,关于 RISC-V RVV 的版本差异情况可参考 「RISC-V 官方 GitHub」。
6.4.1 taOpenCV API 功能扩展
OpenCV 原生支持的一些 API 函数,如 imread()、imwrite()、imdecode()、imencode() 等,可以自动识别 JPEG 格式并进行编解码处理。SDK 对这些 API 函数进行了扩展,使其能够自动选择合适的芯片硬件来完成任务。
此外,OpenCV 原生的 imread()、imdecode() 函数在完成 JPEG 解码后返回 BGR packed 格式的图像,而 SDK 扩展了这些接口的行为,使其能够返回 YUV 和 RGB 格式图像。具体地:
- 当接口配置成返回 YUV 时,解码器会根据 JPEG 文件头中提供的颜色通道数和 YUV 采样率确定输出 YUV 图像的具体格式(支持 I400、NV12、NV16)
- 当接口配置成返回 RGB 时,解码器会直接把 YUV 转成用户设置的 RGB 格式输出(支持 Packed、Planar)。值得说明的是,从 YUV 到 RGB 的转换是由解码器内部的后处理单元完成的,没有额外的延迟和 DDR 带宽开销
除此之外,还有多个类别的接口已经支持扩展的 YUV 格式,包括:
- 部分
Mat类的成员函数,如create()、release()、clone()等 - 部分
VideoCapture类的成员函数,如read()、grab()等 - 部分
VideoWriter类的成员函数,如write()接口 - 部分图像处理类接口,如
cvtColor()、resize()等 - 部分 2D 绘图类接口,如
line()、rectangle()、circle()、putText()等
Mat(AVFrame *frame)
描述 通过 AVFrame 创建 Mat 对象。 参数说明
| 参数 | 描述 | 输入/输出 |
|---|---|---|
frame | 与ffmpeg 的 AVFrame 对象对应。 | 输入 |
返回值 返回Mat 对象。
imread( const String& filename, int flags = IMREAD_COLOR )
描述
对图片进行解码操作,taopencv对jpeg解码进行扩展,默认使用硬件进行jpeg解码出BGR数据格式,用户可通过修改flag为IMREAD_COLOR_YUV输出NV12格式,添加IMREAD_RETRY_SOFTDEC即取消硬件加速。
参数说明
| 参数 | 描述 | 输入/输出 |
|---|---|---|
filename | 输入的文件名 | 输入 |
flags | 输入的标志位 | 输入 |
返回值 返回Mat 对象。 注意 如果使用硬件解码jpeg图像,返回的Mat对象内存为tasys分配的内存块
imwrite( const String& filename, InputArray img,const std::vector<int>& params = std::vector<int>());
描述 对Mat进行编码操作,taopencv对jpeg编码进行扩展,支持NV12数据编码为jpeg。我们对params参数进行,可取消硬件加速。
vector<int> params;
params.push_back(cv::IMWRITE_JPEG_HARDWARE); // 取消硬件加速
params.push_back(0);
params.push_back(cv::IMWRITE_JPEG_SAMPLING_FACTOR); // 指定为NV12格式
params.push_back(cv::IMWRITE_JPEG_SAMPLING_FACTOR_NV12);
参数说明
| 参数 | 描述 | 输入/输出 |
|---|---|---|
filename | 输入的文件名 | 输入 |
img | 输入的mat | 输入 |
params | 编码参数 | 输入 |
返回值 返回Mat 对象。 注意 如果使用硬件编码jpeg图像,Mat对象内存必须为tasys分配的内存块
6.4.2 RVV 加速接口
TACO SDK 提供的 taOpenCV 库对部分接口进行了优化,其中,有些接口是使用了 RISC-V RVV 向量指令集实现的加速,下表对此类接口进行了汇总。
| 优化算子 | 支持数据类型 | 参数说明 |
|---|---|---|
add | u8/s8/u16/s16/s32/f32/f64 | 两个数组逐个元素做加运算 |
sub | u8/s8/u16/s16/s32/f32/f64 | 两个数组逐个元素做减运算 |
max | u8/s8/u16/s16/s32/f32/f64 | 两个数组逐个元素求最大值 |
min | u8/s8/u16/s16/s32/f32/f64 | 两个数组逐个元素求最小值 |
mul | u8/s8/u16/s16/s32/f32/f64 | 两个数组逐个元素做乘法运算 |
absdiff | u8/s8/u16/s16/s32/f32/f64 | 两个数组差值的绝对值(求帧差) |
div | u8/s8/u16/s16/s32/f32/f64 | 两个数组逐个元素做除法运算 |
recip | u8/s8/u16/s16/s32/f32/f64 | 数组元素的倒数运算 |
addWeighted | u8/s8/u16/s16/s32/f32/f64 | 两个数组逐个元素做加权相加运算(alpha 运算) |
and/or/xor/not | u8 | 按位做逻辑操作(与/或/异或/非) |
cmp | u8/s8/u16/s16/s32/f32/f64 | 数组元素比较运算 |
split | u8/s8/u16/s32/s64 | 将一个多通道数组分割成多个单通道数组 |
merge | u8/s8/u16/s32/s64 | 将几个单通道数组合并成一个多通道数组 |
fastAtan | f32/f64 | 快速计算反正切值 |
BoxFilter | u8 | 3x3, cn=1, norm |
Resize | u8 | INTER_LINEAR, Area, Nearest |
Threshold | u8/s8/u16/s16/f32/f64 | 图像阈值化 |
Sobel | u8->s16, u8->f32 | Sobel 边缘检测算子,3x3, cn=1; 5x5, cn=1 |
MedianBlur | u8 | 3x3, 5x5 |
BGRtoBGR | u8 | bgr/bgra/rgb/rgba |
BGRtoBGR5x5 | u8 | bgr/bgra/rgb/rgba->bgr565/bgr555 |
BGR5x5toBGR | u8 | bgr565/bgr555->bgr/bgra/rgb/rgba |
BGRtoGray | u8 | bgr/bgra/rgb/rgba->gray |
GraytoBGR | u8 | gray->bgr/bgra/rgb/rgba |
BGRtoYUV | u8 | bgr/bgra/rgb/rgba->YUV Planar |
YUVtoBGR | u8 | YUV Planar->bgr/bgra/rgb/rgba |
BGRtoXYZ | u8 | bgr/bgra/rgb/rgba->XYZ |
XYZtoBGR | u8 | XYZ->bgr/bgra/rgb/rgba |
TwoPlaneYUVtoBGR | u8 | YUV Semi-Planar (NV12/NV21/etc.) |
ThreePlaneYUVtoBGR | u8 | YUV Planar (YUV420P/etc.) |
BGRtoThreePlaneYUV | u8 | YUV Planar (YUV420P/etc.) |
BGRtoTwoPlaneYUV | u8 | YUV Semi-Planar (NV12/NV21/etc.) |
OnePlaneYUVtoBGR | u8 | 单平面 YUV 转 BGR |
Dilate | u8 | 3x3, cn=1,4; 4x4, cn=1; 5x5, cn=1; 15x15, cn=1 |
Erode | u8 | 3x3, cn=1,4; 4x4, cn=1; 5x5, cn=1; 15x15, cn=1 |
WarpAffine | u8 | INTER_LINEAR (BORDER_REPLIATE/CONSTANT) NEAREST (BORDER_REPLIATE/CONSTANT) |
WarpPrespective | u8 | INTER_LINEAR (BORDER_REPLIATE/CONSTANT) |
GaussianBlur | u8 | 7x7, cn=1 |
PyrDown | u8 | BORDER_CONSTANT, cn=1/2/3/4 |
OptFlowPyrLK | u8 | 光流金字塔 LK 算法 |
countNTaonZero | u8 | cn=1 |
convert | u8/s8/u16/s16/s32/f32/f64 | 数据类型转换 |
norm1 | u8 | L2, no mask |
minMaxLo | f32 | max_val, no mask |
calcMinEigenVal | f32 | 计算最小特征值 |
calcHarris | f32 | Harris 角点检测 |
6.4.3 taOpenCV 示例程序
#include "opencv2/opencv.hpp"
#include <iostream>
cv::Mat image, scaled;
static void ta_convertRGB2NV12(Mat &src, Mat &dst) {
int cropWidth = src.cols / 2 * 2;
int cropHeight = src.rows / 2 * 2;
cv::Mat cropImage = src(cv::Rect(0, 0, cropWidth, cropHeight));
// std::ofstream ofs;
// ofs.open(outputFilePath, std::ios::binary);
// 创建一个YUV图像来存储转换后的数据
cv::Mat yuvImage(cropImage.rows * 3 / 2, cropImage.cols, CV_8UC1,
cv::Scalar(0)); // Y分量
// cv::Mat uvImage(cropImage.rows *3/ 2, cropImage.cols, CV_8UC1,
// cv::Scalar(0)); // UV分量 (NV12)
// 进行BGR到YUV颜色空间转换
cv::cvtColor(src, yuvImage, cv::COLOR_BGR2YUV_I420);
memcpy(dst.data, yuvImage.data, cropImage.cols * cropImage.rows);
int yLen = cropImage.cols * cropImage.rows;
int uvLen = cropImage.cols * cropImage.rows / 4;
// 将UV分量(U和V)从I420格式提取并排列为NV12格式
for (int el = 0; el < uvLen; el++) {
dst.data[yLen + 2 * el] = yuvImage.data[yLen + el];
dst.data[yLen + 2 * el + 1] = yuvImage.data[yLen + el + uvLen];
}
return;
}
int main( int argc, const char** argv )
{
std::string filename = "./fruits.jpg";
image = cv::imread(filename , cv::IMREAD_COLOR | cv::IMREAD_RETRY_SOFTDEC);
//error handling skipped
Mat image_nv12;
image_nv12.allocator = hal::getAllocator();
image_nv12.create(image.rows * 3 /2,image.cols,CV_8UC1);
ta_convertRGB2NV12(image, image_nv12);//convert to nv12
cv::resize(image_nv12, scaled, cv::Size(100,100), 0, 0, cv::INTER_LINEAR);
cv::imwrite("./output.jpg", scaled);
return 0;
}
6.5 taFFmpeg 接口说明
TACO SDK 提供的 taFFmpeg 基于 FFmpeg 官方的 4.3.2 版本,我们对 FFmpeg 进行了一些扩展,使其能够自动选择合适的芯片硬件来完成任务。前文已经对 taFFmpeg 有了一些描述,这个章节对支持的编解码器进行补充说明。
6.5.1 视频解码器
用户可通过如下命令来查询 taFFmpeg 支持的解码器。
ffmpeg -decoders
其结果中应包含由 TACO SDK 提供的硬件加速版 H.264 解码器,名称为 h264_taco。
用户可以通过如下命令行查询硬件解码器提供的一些额外选项:
ffmpeg -h decoder=h264_taco
ffmpeg -h decoder=hevc_taco
目前已经支持的选项有:
| 参数名称 | 功能描述 | 取值范围 | 默认值 |
|---|---|---|---|
vdec_output_semi_planar | 指定输出图像的平面格式 | 0 ~ 输出 YUV420 Planar 图像;1 ~ 输出 YUV420 Semi-planar 图像 | 0 |
vdec_extra_frame_buffer_num | 额外提供的帧缓存数量 | 大于等于 1 的整数 | 2 |
vdec_stream_addr_type | Bitstream 数据指针的类型 | 0 ~ 物理地址,页面连续;1 ~ 虚拟地址,页面连续;2 ~ 虚拟地址,页面不保证连续 | 0 |
vdec_fps_decimation | 解码后哪些帧需要写入 DDR | 0 ~ 全部写入 DDR;1 ~ 写一帧跳一帧;2 ~ 写一帧跳两帧 | 0 |
这些选项可以使用 taFFmpeg 提供的 av_dict_set() 接口进行设置。
6.5.2 视频编码器
用户可通过如下命令来查询 taFFmpeg 支持的编码器。
ffmpeg -encoders
其结果中应包含由 TACO SDK 提供的硬件加速版 H.264 编码器,名称为 h264_taco。
用户可以通过如下命令行查询硬件编码器提供的一些额外选项:
ffmpeg -h encoder=h264_taco
目前已经支持的选项有:
| 参数名称 | 功能描述 | 取值范围 | 默认值 |
|---|---|---|---|
venc_quality_mode | 指定编码的质量模式 | 0 ~ 速度优先,质量低;1 ~ 均衡模式;2 ~ 质量优先,速度低 | 2 |
venc_gop_size | 设置一个 GOP 包含的帧数 | 大于等于 1 的整数 | 30 |
venc_rc_mode | 码率控制算法 | 0 ~ fixed qp;1 ~ vbr;2 ~ cbr | 2 |
venc_yuv_addr_type | YUV 数据指针的类型 | 0 ~ 物理地址,页面连续;1 ~ 虚拟地址,页面连续;2 ~ 虚拟地址,页面不保证连续 | 0 |
这些选项可以使用 taFFmpeg 提供的 av_dict_set() 接口进行设置。
6.5.3 JPEG 解码器
用户可以通过如下命令行查询硬件 JPEG 解码器是否已安装:
ffmpeg -decoders | grep jpeg_taco
用户可以通过如下命令行查询 JPEG 硬件解码器提供的一些额外选项:
ffmpeg -h decoder=jpeg_taco
目前已经支持的选项有:
| 参数名称 | 功能描述 | 取值范围 | 默认值 |
|---|---|---|---|
jdec_bs_buffer_size | 设置输入流缓冲区的大小 | 大于 0 的整数 | 2 |
jdec_extra_frame_buffer_num | 额外提供的帧缓存数量 | 大于等于 0 的整数,建议:Jpeg 可以为 0,mjpeg 大于 0 | 2 |
jdec_stream_addr_type | Bitstream 数据指针的类型 | 0 ~ 物理地址,页面连续;1 ~ 虚拟地址,页面连续;2 ~ 虚拟地址,页面不保证连续 | 0 |
这些选项可以使用 taFFmpeg 提供的 av_dict_set() 接口进行设置。
6.5.4 JPEG 编码器
用户可以通过如下命令行查询硬件编码器提供的一些额外选项:
ffmpeg -encoders | grep jpeg_taco
用户可以通过如下命令行查询 JPEG 硬件解码器提供的一些额外选项:
ffmpeg -h encoder=jpeg_taco
目前已经支持的选项有:
| 参数名称 | 功能描述 | 取值范围 | 默认值 |
|---|---|---|---|
jenc_bs_buffer_size | 设置输出流缓冲区的大小 | 大于 0 的整数 | 500*1024 |
jenc_yuv_addr_type | YUV 数据指针的类型 | 0 ~ 物理地址,页面连续;1 ~ 虚拟地址,页面连续;2 ~ 虚拟地址,页面不保证连续 | 0 |
6.5.5 结构体定义
AVFrame 结构体的定义位于 libavutil/frame.h 中,它封装了一个视频帧的多种信息,包括图像数据(编码前或解码后的未压缩数据)、时间戳、像素格式、分辨率等。
下面是一些关键字段的介绍:
data: 指针数组,每个指针指向视频帧数据的一个颜色通道(数据平面)。例如,对于 ffmpeg 默认的 YUV420P 格式,data[0]指向 Y 分量,data[1]和data[2]分别指向 U 和 V 分量linesize: 数组,对于图像的每个颜色通道,记录它的一行数据在内存中实际占用的字节数。它的大小取决于像素格式以及数据对齐要求。而数据对齐要求一般是源于生成或者消费这帧图像的硬件的特性format: 视频帧的像素格式(例如AV_PIX_FMT_YUV420P)width,height: 视频帧的宽度和高度pts,pkt_dts: 时间戳信息,用于表示帧的显示时间
在使用 taFFmpeg 进行视频处理时,通常会涉及到以下接口:
- 解码: 使用
avcodec_receive_frame()接口从解码器获取解码后的视频帧 - 处理: 使用
sws_scale()接口对AVFrame中的数据进行缩放、裁剪或格式转换等视频处理操作 - 编码: 使用
avcodec_send_frame()接口将处理后的AVFrame帧编码为压缩格式 - 释放: 使用
av_frame_free()释放AVFrame结构体占用的内存
AVPacket 是 taFFmpeg 中很重要的一个数据结构,其中 A 代表 Audio,V 代表 Video。AVPacket 用于保存解复用之后、解压缩之前的音视频数据,以及关于这些数据的一些附加信息(side data),例如,显示时间戳(pts)、解码时间戳(dts)、数据时长(duration)、所在流媒体的索引(stream_index)等。
在使用 AVPacket 时有几个重要事项需要注意:
AVPacket的本质是一个数据描述体,它本身并不随身携带媒体数据,而是通过data指针指向音视频数据的缓存位置。所以,当对AVPacket结构体进行复制的时候,它所描述的音视频数据并没有被复制AVPacket结构体描述视频时,它通常只包含一个完整的 Frame,而音频则有可能包含多个 Frame- 允许存在一种特殊的
AVPacket,它只含有附加信息(side data)而没有音视频数据(data)